package com.hospital.hl7package.module.controller;

import ca.uhn.hl7v2.model.DataTypeException;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.model.v24.message.SIU_S12;
import ca.uhn.hl7v2.parser.ModelClassFactory;
import ca.uhn.hl7v2.parser.PipeParser;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.hospital.common.core.exception.ExceptionPrint;
import com.hospital.common.core.result.ErrorTip;
import com.hospital.common.core.result.SuccessTip;
import com.hospital.common.core.result.Tip;
import com.hospital.common.core.utils.DateUtil;
import com.hospital.hl7package.function.Hl7HelpperFunc;
import com.hospital.hl7package.module.entity.HL7MessageEntity;
import com.hospital.hl7package.module.entity.Hl7MessageLogs;
import com.hospital.hl7package.module.entity.Hl7MessageRequest;
import com.hospital.hl7package.module.service.DrugPrescMasterService;
import com.hospital.hl7package.module.service.Hl7MessageLogsService;
import com.hospital.hl7package.module.service.OperationMasterService;
import com.hospital.hl7package.utils.HL7Util;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StopWatch;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/info")
public class Hl7PackageController {

    @Value("${logsUrlPart}")
    private  String logsUrlPart;
    @Value("${serviceUrlPart}")
    private   String serviceUrlPart;
    @Value("${prescFunction}")
    private String prescFunction;
    @Autowired
    private Hl7HelpperFunc hl7HelpperFunc;

    @Resource
    private OperationMasterService operationMasterService;
//    @Autowired
//    private MqSendService mqSendService;

    @Resource
    private Hl7MessageLogsService hl7MessageLogsService;

    @Resource
    private DrugPrescMasterService drugPrescMasterService;



    @RequestMapping(value = "/hl7Message", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public Tip sendHL7Message(@RequestBody String params) throws DataTypeException {
        String guid = null;
        String hospitalName = null;
        String messageType = "AE";
        try {
            HL7MessageEntity hl7MessageEntity = JSON.parseObject(params, HL7MessageEntity.class);
            String strMessage = hl7MessageEntity.getHl7Message().substring(hl7MessageEntity.getHl7Message().indexOf('&'));
            String sendMessage = "MSH|^~\\" + strMessage;
            ModelClassFactory theFactory = null;
            PipeParser parser = new PipeParser(theFactory);

            Map<String, Object> map = new HashMap<>();
            try {
                Message message = parser.parse(sendMessage);
                if (message instanceof SIU_S12) {
                    SIU_S12 siu_s12 = (SIU_S12) message;
                    guid = siu_s12.getMSH().getMessageControlID().getValue();
                    hospitalName = siu_s12.getMSH().getMsh20_AlternateCharacterSetHandlingScheme().getValue();
                    map = hl7HelpperFunc.setOperationInfo(siu_s12);
                }
//                XMLParser xmlParser = new DefaultXMLParser();
//                String xmlstring = xmlParser.encode(message);

                if (operationMasterService.saveOperation(map)) {
                    messageType = "AA";
                }
                return new SuccessTip(hl7HelpperFunc.getAck(hospitalName, guid, "HTSoftWare", "HTSoftWare", "DoCare", "DoCare", messageType, "SIU", "S14", "2.4"));
            } catch (Exception e) {
                log.error(e.toString());
                return new SuccessTip(hl7HelpperFunc.getAck(hospitalName, guid, "HTSoftWare", "HTSoftWare", "DoCare", "DoCare", messageType, "SIU", "S14", "2.4"));
            }
        } catch (Exception ex) {
            log.error(ex.toString());
            return new SuccessTip(hl7HelpperFunc.getAck(hospitalName, guid, "HTSoftWare", "HTSoftWare", "DoCare", "DoCare", messageType, "SIU", "S14", "2.4"));

        }
    }

    /**
     * 推送HL7文件内容
     *
     * @param params
     * @param response
     * @param result
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/sendHL7", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public Tip changeHL7Message(@RequestBody String params, HttpServletResponse response, BindingResult result) throws Exception {
        StopWatch stopwatch = new StopWatch();
        stopwatch.start();
        String startTime = DateUtil.getAllTime();
        Tip tip = new SuccessTip("");
        HttpResponse execute = null;
        try {
            Hl7MessageRequest hl7MessageRequest = JSON.parseObject(params, Hl7MessageRequest.class);
            List<Hl7MessageLogs> stringList = HL7Util.getHl7Message(hl7MessageRequest,hl7MessageLogsService,
                    logsUrlPart,serviceUrlPart,prescFunction,drugPrescMasterService);
//        SendResult send = mqSendService.send(returnStr, "lab", "applyInfo");
//        return new SuccessTip<>(returnStr + "--RocketMq--SendStatus:" + send.getSendStatus());
//            String logsUrlPart = hl7MessageLogsService.getLogs();
            if (hl7MessageRequest.getUrl() == null) {
                tip =  new ErrorTip(1001, "无推送地址无法推送消息：" + params);
                return tip;
            }
            if (stringList.size() == 0){
                return tip;
            }
            for (Hl7MessageLogs hl7MessageLogs : stringList) {
                String asciiToString = hl7MessageLogs.getBmessage()==null?"":new String(hl7MessageLogs.getBmessage(),"gbk");
                String returnStr = hl7MessageLogs.getMessage()==null? asciiToString ==null?"":asciiToString:hl7MessageLogs.getMessage();
                if (returnStr.trim().length()>0) {
                    try {
                        execute = HttpRequest.post(hl7MessageLogs.getSendUrl()).header("Content-Type", "text/plain;charset=UTF-8").body(returnStr).execute();
                        if (execute.getStatus() != 200) {
                            ExceptionPrint.printString(hl7MessageRequest.getType(), params, execute.getStatus() + "===" + execute.body(), returnStr, "1", hl7MessageLogs.getSendUrl());
                            hl7MessageLogs.setStatus("0");
                            hl7MessageLogs.setCount(0);
                        } else {
                            if (execute.body().contains("MSA|AA|")) {
                                ExceptionPrint.printString(hl7MessageRequest.getType(), params, execute.body(), returnStr, "2", hl7MessageLogs.getSendUrl());
                                hl7MessageLogs.setStatus("1");
                                hl7MessageLogs.setResVal(execute.body());
                            } else {
                                ExceptionPrint.printString(hl7MessageRequest.getType(), params, execute.body(), returnStr, "3", hl7MessageLogs.getSendUrl());
                                hl7MessageLogs.setStatus("0");
                                hl7MessageLogs.setCount(0);
                                hl7MessageLogs.setResVal(execute.body());
                            }
                        }
                    } catch (Exception e) {
                        ExceptionPrint.printString(hl7MessageRequest.getType(), params, e.getMessage(), returnStr, "4", hl7MessageLogs.getSendUrl());
                        hl7MessageLogs.setStatus("0");
                        hl7MessageLogs.setCount(0);
                    } finally {
                        hl7MessageLogsService.saveOrUpdate(hl7MessageLogs);
                    }
                }
            }
            tip = new SuccessTip(params + "--推送平台返回：" + execute.body()==null?"":execute.body());
        } catch (Exception e) {
            tip = new ErrorTip(1001, e.getMessage());
        }finally {
            stopwatch.stop();
            String endTime = DateUtil.getAllTime();
            ExceptionPrint.printCommString("XML文件内容转HL7并推送",params,String.valueOf(tip.getCode()),tip.getMessage()+tip.getData(),startTime,endTime,String.valueOf(stopwatch.getTotalTimeSeconds()));
        }
        return tip;
    }



    @RequestMapping(value = "/sendHL7replace", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public Tip HL7Message(@RequestBody String params, HttpServletResponse response, BindingResult result) throws Exception {
        Hl7MessageRequest hl7MessageRequest = JSON.parseObject(params, Hl7MessageRequest.class);
        String filePath = hl7MessageRequest.getFilename();
        String readText = null;
        File file = new File(filePath);
        InputStream in = new FileInputStream(file);
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(in);
        Element rootElement = document.getRootElement();
        Element oml_o211 = rootElement.element("OML_O21");
        List orc = oml_o211.elements("ORC");
        for (Iterator<?> it = orc.iterator(); it.hasNext(); ) {
            Element e = (Element) it.next();
            e.element("ORC_1").setText("OH");
            e.element("ORC_5").setText("IP");
        }
        List obr = oml_o211.elements("OBR");
        for (Iterator<?> it = obr.iterator(); it.hasNext(); ) {
            Element e = (Element) it.next();
            e.element("OBR_5").setText("1");
        }
        try {
            readText = document.asXML();
        } catch (Exception e) {
            log.error(filePath + ":读取该文件失败！");
        }
        if (hl7MessageRequest.getUrl() != null && !hl7MessageRequest.getUrl().equals("")) {
            HttpResponse execute = HttpRequest.post(hl7MessageRequest.getUrl()).header("Content-Type", "text/plain").body(readText).execute();
            if (execute.getStatus() != 200) {
                log.error(filePath + "检验HL7计费消息推送失败！" + execute.body());
            }
        }
        return new SuccessTip(readText);
    }

}
